using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;

using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging.Configuration;

using Microsoft.Practices.EnterpriseLibrary.Logging;
using Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;

using Microsoft.Practices.EnterpriseLibrary.Logging.Properties;

namespace SBPweb.Logging
{
	/// <summary>
	/// EntLib base class for custom text formatters.
	/// </summary>
	[ConfigurationElementType(typeof(CustomFormatterData))]
	public class EntLibTextFormatter : TextFormatter
	{
		private const string DEFAULTTEMPLATE = "Timestamp: {timestamp}{newline}Message: {message}{newline}Category: {category}{newline}Keyword: {keyword}{newline}Priority: {priority}{newline}EventId: {eventid}{newline}Severity: {severity}{newline}Title:{title}{newline}Machine: {machine}{newline}App Domain: {appDomain}{newline}ProcessId: {processId}{newline}Process Name: {processName}{newline}Thread Name: {threadName}{newline}Win32 ThreadId:{win32ThreadId}{newline}";

		private const string keywordToken = "{keyword}";

		/// <summary>
		/// Registers this instance as an uninitialized text formatter.
		/// </summary>
		/// <remarks>
		/// The uninitialized text formatters can become initialized by calling <see cref="LogManager.Initialize()"/>.
		/// This method supports the EntLib infrastructure.
		/// </remarks>
		public EntLibTextFormatter()
			/*: this(Resources.DefaultTextFormat)*/
			: base()
		{
			LogManager.AddUninitializedTextFormatter(this);
		}

		/// <summary>
		/// This constructor supports ObjectBuilder.
		/// </summary>
		/// <param name="nvc"></param>
		public EntLibTextFormatter(NameValueCollection nvc)
			: base()
		{
			LogManager.AddUninitializedTextFormatter(this);
		}

		/// <summary>
		/// Provides a textual representation of a keyword list.
		/// </summary>
		/// <param name="Keywords">The collection of keywords.</param>
		/// <returns>A comma delimited textural representation of the keywords.</returns>
		public static string FormatKeywordsCollection(ICollection<string> Keywords)
		{
			StringBuilder klb = new StringBuilder();
			int i = 0;
			foreach (String keyword in Keywords)
			{
				klb.Append(keyword);
				if (++i < Keywords.Count)
				{
					klb.Append(", ");
				}
			}
			return klb.ToString();
		}

		/// <summary>
		/// Formats the <see cref="LogEntry"/> object by replacing tokens with values writing the format result
		/// to a <see cref="StringBuilder"/>.
		/// </summary>
		/// <param name="templateBuilder">The <see cref="StringBuilder"/> that holds the formatting result.</param>
		/// <param name="log">Log entry to format.</param>
		/// <returns>Formatted string with tokens replaced with property values.</returns>
		protected override string Format(StringBuilder templateBuilder, LogEntry log)
		{
			base.Format(templateBuilder, log);

			templateBuilder.Replace(keywordToken, log.ExtendedProperties.ContainsKey("Keywords") && log.ExtendedProperties["Keywords"] is ICollection<String> ? FormatKeywordsCollection(log.ExtendedProperties["Keywords"] as ICollection<String>) : "");

			return templateBuilder.ToString();
		}

		/// <summary>
		/// Called by <see cref="LogManager"></see> to initialize related objects.
		/// </summary>
		/// <remarks>
		/// By calling this the <see cref="LogManager"/> transforms this instance to be initialized and removes it from the collection
		/// of uninitialized formatters. The initialization process can be started by calling <see cref="LogManager.Initialize()"/>.
		/// This method supports the EntLib infrastructure.
		/// </remarks>
		protected internal virtual void InitializeRelatedObjects()
		{
			this.Template = DEFAULTTEMPLATE;
		}
	}
}
